<template>
  <div v-bind="$attrs" ref="pieChartRef"></div>
</template>

<script lang="ts" setup>
/*
 * initData: 除了数据外的其他设置
 * {
 *   title: '覆盖原始title对象设置',  // title与titleText选一
 *   titleText: '设置title.text'，  // title与titleText选一
 *   legend: {},  // 可选，同上
 *   series: [],  // 可选，同上
 *   dataset: {}, // 必填，直接覆盖！！！！
 * }
 * updateData: dataset
 *
 * */
import * as echarts from "echarts/core";
import {
  PieChart,
  // 系列类型的定义后缀都为 SeriesOption
  PieSeriesOption,
} from "echarts/charts";
import {
  TitleComponent,
  // 组件类型的定义后缀都为 ComponentOption
  TitleComponentOption,
  TooltipComponent,
  TooltipComponentOption,
  GridComponent,
  GridComponentOption,
  LegendComponent,
  LegendComponentOption,
  // 数据集组件
  DatasetComponent,
  DatasetComponentOption,
  // 内置数据转换器组件 (filter, sort)
  TransformComponent,
} from "echarts/components";
// import { LabelLayout, UniversalTransition } from "echarts/features";
import { CanvasRenderer } from "echarts/renderers";

import {
  titleColor,
  seriesColor,
  tooltipBgColor,
  axisLabelColor,
} from "./const";
import type { RequiredAtLeastOne } from "#/index";
import type { AddEchartInstance } from "@/layout";

// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
type ECOption = echarts.ComposeOption<
  | PieSeriesOption
  | TitleComponentOption
  | TooltipComponentOption
  | GridComponentOption
  | DatasetComponentOption
  | LegendComponentOption
>;

// 注册必须的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  DatasetComponent,
  TransformComponent,
  PieChart,
  // LabelLayout,
  // UniversalTransition,
  CanvasRenderer,
]);

interface InitDataOrigin {
  title?: object;
  titleText?: string;
  [key: string]: any;
}
type InitData = RequiredAtLeastOne<InitDataOrigin, "title" | "titleText">;
// updateData
interface Dataset {
  source: Array<Array<string | number>>;
}
interface UpdateData {
  dataset: Dataset;
}
interface Props {
  initData: InitData;
  updateData: UpdateData;
}
const props = defineProps<Props>();

let myChart: any = null;
const pieChartRef = ref();

const addAfterEnterFuncs: AddEchartInstance | undefined =
  inject("addAfterEnterFuncs");

watch(
  () => props.updateData,
  (val: UpdateData) => {
    myChart && myChart.clear();
    nextTick(() => {
      updateDataChange(val);
    });
  }
);

function checkData(val: UpdateData) {
  return (
    val.dataset &&
    val.dataset.source &&
    Array.isArray(val.dataset.source) &&
    val.dataset.source.length
  );
}

let addFlag = false;
const updateDataChange = (val: UpdateData) => {
  if (checkData(val)) {
    console.log("line", myChart);
    if (!addFlag) {
      addAfterEnterFuncs && addAfterEnterFuncs(renderChart);
      addFlag = true;
    } else {
      renderChart();
    }
  }
};
const renderChart = () => {
  initChart();
  updateChart();
};

function updateChart() {
  myChart.setOption({
    dataset: props.updateData.dataset,
    series: getSeries(),
  });
}
function initChart() {
  myChart = myChart || echarts.init(pieChartRef.value as HTMLElement);
  const option: ECOption = {
    title: props.initData.title || {
      text: props.initData.titleText,
      textStyle: {
        color: titleColor,
        fontSize: 16,
        fontWeight: "normal",
      },
    },
    legend: {
      show: false,
      ...(props.initData.legend || {}),
    },
    grid: {
      ...(props.initData.grid || {}),
    },
    tooltip: {
      show: true,
      confine: true,
      padding: 10,
      backgroundColor: tooltipBgColor,
      borderWidth: 0,
      textStyle: {
        fontSize: 12,
        color: "#dAe8fd",
      },
      ...(props.initData.tooltip || {}),
    },
    dataset: [
      {
        source: [],
      },
    ],
    series: [],
  };
  myChart.setOption(option);
}
function getSeries(): object | object[] {
  const initConfig: object = {
    type: "pie",
    radius: "50%",
    avoidLableOverlap: true,
    selectedMode: "single",
    center: ["50%", "50%"],
    startAngle: 135,
    color: seriesColor,
    itemStyle: {
      borderRadius: 4,
      borderColor: "#fff",
      borderWidth: 1,
    },
    label: {
      position: "outside",
      fontSize: 12,
      color: axisLabelColor,
      //                            width: 80,
      //                        overflow: 'truncate',
      //                        ellipsis: '...'
    },
    labelLine: {
      // length: 20,
      // length2: 0,
      // maxSurfaceAngle: 80,
      lineStyle: {
        color: "#707070",
        width: 1,
      },
    },
    // labelLayout: (params: any) => {
    //   const isLeft = params.labelRect.x < myChart.getWidth() / 2;
    //   const points = params.labelLinePoints;
    //   // Update the end point.
    //   points[2][0] = isLeft
    //     ? params.labelRect.x
    //     : params.labelRect.x + params.labelRect.width;
    //   return {
    //     dy: -16,
    //     labelLinePoints: points,
    //   };
    // },
    //                    itemStyle:{
    //                        normal:{
    //                            borderWidth: 4,
    //                            borderColor:'#16171c',
    //                        },
    //                    },
    // datasetIndex:0
  };
  const initSeries = props.initData.series;
  // 自定义配置了series，按照用户配置的series显示数据的维度
  if (initSeries) {
    // 如果是数组，遍历数组每一项 并 合并配置
    if (Array.isArray(initSeries)) {
      return initSeries.map((item, index) => {
        return {
          ...initConfig,
          ...item,
        };
      });
    } else if (initSeries instanceof Object) {
      // 如果是对象，直接合并后返回
      return {
        ...initConfig,
        ...initSeries,
      };
    } else {
      return initConfig;
    }
  } else {
    // 否则根据dataset中的数据显示维度
    return (
      props.updateData.dataset.source[0].slice(1).reduce((prev: object[]) => {
        return prev.concat(initConfig);
      }, []) || {}
    );
  }
}
</script>
